package com.mian.server;

import com.alibaba.fastjson.JSONObject;
import com.mian.bean.RpcRequest;
import com.mian.bean.RpcResponse;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import org.springframework.cglib.reflect.FastClass;
import org.springframework.cglib.reflect.FastMethod;

import java.util.Map;

public class NettyServerHandler extends ChannelInboundHandlerAdapter {

	private final Map<String, Object> handerMap;

	public NettyServerHandler(Map<String, Object> handerMap) {
		this.handerMap = handerMap;
	}

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

		RpcRequest request = JSONObject.parseObject(msg.toString(),RpcRequest.class);

		RpcResponse rpcResponse = new RpcResponse();
		rpcResponse.setRequestId(request.getRequestId());
		try{
			Object result = handler(request);
			rpcResponse.setResult(result);
			Thread.sleep(700);
		}catch (Exception e){
			rpcResponse.setException(e);
		}
		System.out.println(request.getRequestId()+"执行完毕....");
		ctx.channel().writeAndFlush(JSONObject.toJSONString(rpcResponse));
		ctx.channel().writeAndFlush("\r\n");
		
	}

	private Object handler(RpcRequest rpcRequest) throws Exception {

		String serviceName = rpcRequest.getInterfaceName();

		Object serviceBean = handerMap.get(serviceName);
		if (serviceBean == null){
			throw new RuntimeException(String.format("can not find service bean by key: %s", serviceName));
		}

		// 知道类 就能够创建 fastClass
		FastClass fastClass = FastClass.create(serviceBean.getClass());

		// 知道类，方法名，参数类型 就可以创建 fastMethod
		FastMethod fastMethod = fastClass.getMethod(rpcRequest.getMethodName(), rpcRequest.getParameterTypes());

		Object result = fastMethod.invoke(serviceBean, rpcRequest.getParameters());

		return result;
	}



	@Override
	public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
		if(evt instanceof IdleStateEvent){
			IdleStateEvent event = (IdleStateEvent)evt;
			if(event.state().equals(IdleState.READER_IDLE)){
				System.out.println("读空闲===");
				ctx.channel().close();
			}else if(event.state().equals(IdleState.WRITER_IDLE)){
				System.out.println("写空闲=====");
			}else if(event.state().equals(IdleState.ALL_IDLE)){
				System.out.println("读写空闲");
				ctx.channel().writeAndFlush("ping\r\n");
			}

		}
		
	}

	
	
}
